package lab3.systemA;

import java.io.*;

/**
 * Filtrul are un port de intrare si doua porturi de iesire. </br>
 * 
 * Filtrul citeste date de la portul de intrare si le transfera la porturile de
 * iesire daca este indeplinita o anumita conditie. </br>
 * 
 * Datele sunt transferate la portul de iesire "approved" daca studentul a
 * absolvit un curs dat, in caz contrat datele sunt transferate la portul de
 * iesire "rejected".
 */
public class CourseFilter extends Filter {

	/**
	 * Portul de intrare.
	 **/
	protected BufferedReader pInput;

	/**
	 * Portul de iesire "approved".
	 **/
	protected BufferedWriter pOutputApproved;

	/**
	 * Portul de iesire "rejected".
	 **/
	protected BufferedWriter pOutputRejected;

	/**
	 * Numarul cursului
	 **/
	protected int iCourse;

	/**
	 * Construirea unui filtru pentru curs cu un nume dat. </br>Porturile de
	 * intrare si de iesire sunt impachetate intr-un flux de caractere
	 * buffer-at. </br> Aceasta permite utilizarea de diferite mecanisme de I/E
	 * dar si utilizarea de conducte (pipes). De exemplu, un fisier poate fi
	 * conectat direct la un filtru.
	 * 
	 * @param sName
	 *            sirul ce reprezinta numele filtrului
	 * @param pInput
	 *            portul de intrare al acestui filtru
	 * @param pOutputApproved
	 *            portul de iesire "approved" al acestui filtru
	 * @param pOutputRejected
	 *            portul de iesire "rejected" al acestui filtru
	 * @param iCourse
	 *            numarul cursului
	 */
	public CourseFilter(String sName, BufferedReader pInput, BufferedWriter pOutputApproved, BufferedWriter pOutputRejected, int iCourse) {
		// Executarea constructorului din clasa parinte.
		super(sName);

		// Initializarea porturilor de intrare si iesire.
		this.pInput = pInput;
		this.pOutputApproved = pOutputApproved;
		this.pOutputRejected = pOutputRejected;

		// Setarea numarului cursului.
		this.iCourse = iCourse;
	}

	/**
	 * Indica disponibilitatea datelor pe portul de intrare.
	 * 
	 * @return <code>true</code> daca si numai daca acest filtru poate citi date
	 *         de la portul de intrare.
	 * @throws IOException
	 */
	protected boolean ready() throws IOException {
		return this.pInput.ready();
	}

	/**
	 * Citeste datele disponibile de la portul de intrare si le scrie la
	 * porturile de iesire: daca studentul reprezentat de datele citite a
	 * absolvit cursul dat ca parametru de intrare la crearea acestui filtru
	 * atunci datele sunt scrise la portul de iesire "approved" iar in caz
	 * contrar la portul de iesire "rejected".
	 * 
	 * @throws IOException
	 */
	protected void work() throws IOException {
		// Citeste o inregistrare corespunzatoare unui student, de la portul de
		// intrare.
		Student objStudent = new Student(this.pInput.readLine(), true);

		// Scrie inregistrarea corespunzatoare studentului la unul din porturile
		// de iesire in functie de faptul daca studentul a absolvit cursul dat
		// ca parametru de intrare sau nu l-a absolvit.
		if (objStudent.hasCompleted(this.iCourse)) {
			this.pOutputApproved.write(objStudent.toString());
			this.pOutputApproved.newLine();
			this.pOutputApproved.flush();
		} else {
			this.pOutputRejected.write(objStudent.toString());
			this.pOutputRejected.newLine();
			this.pOutputRejected.flush();
		}
	}

}